package jxau.jwgl.service.impl;

import jxau.jwgl.api.JWGLServerException;
import jxau.jwgl.api.MessageData;
import jxau.jwgl.api.UserApi;
import jxau.jwgl.api.WebApiFactory;
import jxau.jwgl.commons.entity.User;
import jxau.jwgl.service.ServiceException;
import jxau.jwgl.service.UserService;
import jxau.jwgl.utils.net.OkHttpBuilder;
import okhttp3.ResponseBody;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import retrofit2.Call;
import retrofit2.Response;

import java.io.IOException;
import java.net.HttpCookie;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * UserServiceImpl
 *
 * @author LongShu 2017/06/04
 */
@Service
public class UserServiceImpl implements UserService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    // username -> guid
    private static ConcurrentMap<String, String> guidCache = new ConcurrentHashMap<>();

    private UserApi userApi = WebApiFactory.get(UserApi.class);

    @Override
    public User login(User user) throws ServiceException {
        Call<MessageData<Map<String, String>>> call = userApi.login(user.getUsername(), user.getPassword());
        try {
            MessageData<Map<String, String>> messageData = call.execute().body();
            if (messageData.isSuccess()) {
                String guid = messageData.getMessage();
                guidCache.put(user.getUsername(), guid);
                user.setName(messageData.getData().get(0).get("TrueName"));
                user.setTicket(getTicket(guid));
                user.setPassword(null);
            } else {
                throw new ServiceException("登录失败,用户名或密码错误!");
            }
        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
            throw new JWGLServerException("教务系统错误,登录失败!");
        }
        return user;
    }

    @Override
    @Cacheable(cacheNames = "user", key = "'userInfo'+#username")
    public Map<String, String> userInfo(User loginUser, String username) {
        String guid = getGuid(loginUser.getUsername());
        try {
            Response<MessageData<Map<String, String>>> response = userApi.userInfo(guid, username).execute();
            MessageData<Map<String, String>> messageData = response.body();
            if (messageData.isSuccess()) {
                Map<String, String> userInfo = messageData.getData().get(0);
                userInfo.remove("SetField");
                return userInfo;
            } else {
                throw new ServiceException("获取用户信息失败!");
            }
        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
            throw new JWGLServerException("教务系统错误,获取用户信息失败!");
        }
    }

    @Override
    public String getGuid(String username) throws ServiceException {
        String guid = guidCache.get(username);
        if (StringUtils.isBlank(guid)) {
            throw new ServiceException("请重新登录!");
        }
        return guid;
    }

    @Override
    public String checkGuid(String username) throws ServiceException {
        String guid = getGuid(username);
        if (StringUtils.isBlank(guid)) {
            return null;
        }

        try {
            Response<MessageData<Object>> response = userApi.checkGuid(guid).execute();
            String ticket = response.body().getMessage();
            logger.debug("ticket:{}", ticket);
            return ticket;
        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
            throw new JWGLServerException("教务系统错误!");
        }
    }

    @Override
    public void exit(String username) throws ServiceException {
        String guid;
        try {
            guid = getGuid(username);
            if (StringUtils.isBlank(guid)) {
                return;
            }
        } catch (ServiceException e) {
            logger.warn(e.getMessage());
            return;
        }

        try {
            Response<ResponseBody> response = userApi.exit(guid).execute();
            if (response.isSuccessful()) {
                guidCache.remove(guid);
            }
        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
            throw new JWGLServerException("教务系统错误,退出失败!");
        }
    }

    /**
     * 从cookie中获取 ticket
     *
     * @param guid GUID
     * @return ticket
     */
    protected String getTicket(String guid) {
        if (StringUtils.isBlank(guid)) {
            return null;
        }
        String ticket = null;

        List<HttpCookie> cookieList = OkHttpBuilder.getCookieManager().getCookieStore().getCookies();
        for (HttpCookie cookie : cookieList) {
            if (guid.equals(cookie.getName())) {
                ticket = cookie.getValue().substring(7);// ticket=XXX
                break;
            }
        }
        return ticket;
    }

}
